/*
 * File :  RCBaseActivity.java
 * Description : RCBaseActivity
 * Author :  王建
 * Time :  16-9-26 下午7:34
 *
 * Copyright (C) 2016 Chengdu Ruichuangzhibo Technology Co., Ltd. All rights reserved.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.wman.sheep.mvc.base;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.umeng.analytics.MobclickAgent;
import com.wman.sheep.R;
import com.wman.sheep.common.application.AbsAppContext;
import com.wman.sheep.common.utils.AppUtils;
import com.wman.sheep.common.utils.StatusBarUtil;
import com.wman.sheep.common.utils.TDevice;
import com.wman.sheep.common.utils.TLog;
import com.wman.sheep.common.utils.ToastUtil;
import com.wman.sheep.okgo.OkGo;
import com.wman.sheep.widget.BaseTitleBar;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Calendar;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

/**
 * Activity抽象基类
 */
public abstract class BaseMVCActivity extends AppCompatActivity implements View.OnClickListener {
    // 上下文实例
    protected Context mContext;
    private RelativeLayout mRootView;
    protected LinearLayout mContentView;
    //顶部渐变的背景
    private View mGradient;
    protected BaseTitleBar mTitleBar;
    //Loading 进度条ViewStub
    protected ViewStub mLoadingViewStub;
    //NetError ViewStub
    protected ViewStub mNetErrorViewStub;
    //Loading View
    protected View mLoadingView;
    //是否重新加载数据
    protected boolean isReLoadData = false;
    //防止Android过快点击造成多次事件
    private static final int MIN_CLICK_DELAY_TIME = 1000;
    private long lastClickTime = 0;

    protected final SparseArray<View> mViews = new SparseArray<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mRootView = (RelativeLayout) View.inflate(this, R.layout.base_root_view, null);
        mGradient = mRootView.findViewById(R.id.view_gradient);
        mTitleBar = (BaseTitleBar) mRootView.findViewById(R.id.include_action_bar);
        mContentView = (LinearLayout) mRootView.findViewById(R.id.rootView);
        mLoadingViewStub = (ViewStub) mRootView.findViewById(R.id.loading_viewstub);

        mNetErrorViewStub = (ViewStub) mRootView.findViewById(R.id.network_error_viewstub);

        setContentView(View.inflate(this, getLayoutID(), null));

        mContentView.addView(View.inflate(this, getLayoutID(), null),
                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT));

        setContentView(mRootView);

        //当FitsSystemWindows设置 true 时，会在屏幕最上方预留出状态栏高度的 padding
        StatusBarUtil.setRootViewFitsSystemWindows(this, true);
        //设置状态栏透明
        StatusBarUtil.setTranslucentStatus(this);
        //一般的手机的状态栏文字和图标都是白色的, 可如果你的应用也是纯白色的, 或导致状态栏文字看不清
        //所以如果你是这种情况,请使用以下代码, 设置状态使用深色文字图标风格, 否则你可以选择性注释掉这个if内容
        if (!StatusBarUtil.setStatusBarDarkTheme(this, true)) {
            //如果不支持设置深色风格 为了兼容总不能让状态栏白白的看不清, 于是设置一个状态栏颜色为半透明,
            //这样半透明+白=灰, 状态栏的文字能看得清
            StatusBarUtil.setStatusBarColor(this, 0x55000000);
        }

        //如果透明，直接把方向改为SCREEN_ORIENTATION_UNSPECIFIED
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
            boolean result = fixOrientation();
            TLog.d("onCreate fixOrientation when Oreo, result = " + result);
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
        }

        mContext = this;

        // 设置activity管理
        AbsAppContext.getActivityManager().addActivity(this);

        if (0 == TDevice.getNetworkType()) {
            showNetErrorView();
        }

        setTitleBar();

        init();
    }

    private boolean fixOrientation() {
        try {
            Field field = Activity.class.getDeclaredField("mActivityInfo");
            field.setAccessible(true);
            ActivityInfo o = (ActivityInfo) field.get(this);
            o.screenOrientation = -1;
            field.setAccessible(false);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private boolean isTranslucentOrFloating() {
        boolean isTranslucentOrFloating = false;
        try {
            int[] styleableRes = (int[]) Class.forName("com.android.internal.R$styleable").getField("Window").get(null);
            final TypedArray ta = obtainStyledAttributes(styleableRes);
            Method m = ActivityInfo.class.getMethod("isTranslucentOrFloating", TypedArray.class);
            m.setAccessible(true);
            isTranslucentOrFloating = (boolean) m.invoke(null, ta);
            m.setAccessible(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isTranslucentOrFloating;
    }

    @Override
    public void setRequestedOrientation(int requestedOrientation) {
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
            TLog.d("avoid calling setRequestedOrientation when Oreo.");
            return;
        }

        super.setRequestedOrientation(requestedOrientation);
    }

    protected void init() {
        initView();
        initIntent(getIntent());
        initData();
        initViewData();
        getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                initViewSC();
            }
        });
    }

    public <T extends View> T bindView(int id) {
        T view = (T) mViews.get(id);
        if (view == null) {
            view = (T) findViewById(id);
            mViews.put(id, view);
        }

        return view;
    }

    public <T extends View> T get(int id) {
        return bindView(id);
    }

    public void setOnClickListener(View.OnClickListener listener, int... ids) {
        if (ids == null) {
            return;
        }
        for (int id : ids) {
            get(id).setOnClickListener(listener);
        }
    }

    /**
     * 绑定当前View所使用的布局
     *
     * @return layout布局ID
     */
    protected abstract int getLayoutID();

    /**
     * 初始化View
     */
    protected abstract void initView();

    /**
     * 得到Intent实例，Intent复用
     */
    protected void initIntent(Intent intent) {
    }

    /**
     * 初始化数据
     */
    protected abstract void initData();

    /**
     * 初始化View数据
     */
    protected abstract void initViewData();

    /**
     * View绘制完成后的初始化
     */
    protected void initViewSC() {
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (!AppUtils.isDebug()) {
            MobclickAgent.onPageStart(getClass().getName());
            MobclickAgent.onResume(this);
        }
    }

    @Override
    protected void onRestart() {
        super.onRestart();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mUiHandler.removeCallbacksAndMessages(null);
        OkGo.getInstance().cancelTag(AbsAppContext.context());
        AbsAppContext.getActivityManager().finishActivity(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (!AppUtils.isDebug()) {
            MobclickAgent.onPageEnd(getClass().getName());
            MobclickAgent.onPause(this);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public boolean isOnDestroyed() {
        if (mContext == null || isDestroyed() || isFinishing()) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        init();
    }

    /**
     * 显示LoadingView
     */
    public void showLoadingView() {
        mLoadingViewStub.setVisibility(View.VISIBLE);
        mLoadingView = mRootView.findViewById(R.id.loading_view);
        mLoadingView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return true;
            }
        });
    }

    /**
     * 隐藏LoadingView
     */
    public void hideLoadingView() {
        if (mLoadingView != null) {
            mLoadingView.setVisibility(View.GONE);
        }
    }

    /**
     * 显示NetErrorView
     */
    public void showNetErrorView() {
        mNetErrorViewStub.setVisibility(View.VISIBLE);
    }


    public BaseTitleBar getBaseTitleBar() {
        if (mTitleBar == null) {
            mTitleBar = (BaseTitleBar) mRootView.findViewById(R.id.include_action_bar);
        }

//        if (mTitleBar == null) {
//            throw new BaseException("没有添加BaseTitleBar");
//        }
        return mTitleBar;
    }

    /**
     * 是否显示顶部阴影线
     *
     * @param isShowTopGradient
     */
    protected void isShowTopGradient(boolean isShowTopGradient) {
        mGradient.setVisibility(isShowTopGradient ? View.VISIBLE : View.GONE);
    }

    private void setTitleBar() {
        if (isShowTitleBar()) {
            mTitleBar.setVisibility(View.VISIBLE);
            mGradient.setVisibility(View.VISIBLE);
        } else {
            mTitleBar.setVisibility(View.GONE);
            mGradient.setVisibility(View.GONE);
            RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) mContentView.getLayoutParams();
            lp.setMargins(0, 0, 0, 0);
            mContentView.setLayoutParams(lp);
        }
    }

    /**
     * 是否显示TitleBar
     *
     * @return
     */
    protected boolean isShowTitleBar() {
        return true;
    }

    /**
     * 显示软键盘
     */
    public void showSoftInput() {
        InputMethodManager manager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        manager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
    }

    /**
     * 隐藏软键盘
     */
    public void hideSoftInput(Context context) {
        InputMethodManager manager = (InputMethodManager) context.getSystemService(INPUT_METHOD_SERVICE);
        if (getCurrentFocus() != null) {
            manager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    /**
     * @param it
     * @return void
     * @Title: startAnimationActivity
     * @Description: 开始动画跳转
     */
    public void startAnimationActivity(Intent it) {
        if (0 == TDevice.getNetworkType()) {
            ToastUtil.showTextToast(AbsAppContext.resources().getString(R.string.common_check_network));
            return;
        }
        startActivity(it);
        overridePendingTransition(R.anim.in_from_right, R.anim.out_of_left);
    }

    /**
     * @param it
     * @param requestCode
     * @return void
     * @Title: startAnimationActivityForResult
     * @Description: 开始动画跳转
     */
    public void startAnimationActivityForResult(Intent it, int requestCode) {
        startActivityForResult(it, requestCode);
        overridePendingTransition(R.anim.in_from_right, R.anim.out_of_left);
    }

    /**
     * @return void
     * @Title: finishAnimationActivity
     * @Description: 动画方式结束页面
     */
    public void finishAnimationActivity() {
        finish();
        overridePendingTransition(R.anim.in_from_left, R.anim.out_of_right);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            finishAnimationActivity();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    final public void onClick(View v) {

        long currentTime = Calendar.getInstance().getTimeInMillis();
        if (currentTime - lastClickTime > MIN_CLICK_DELAY_TIME) {
            lastClickTime = currentTime;
            onNoDoubleClick(v);
        }
    }

    /**
     * 防止Android过快点击造成多次事件
     *
     * @param v
     */
    protected void onNoDoubleClick(View v) {
    }

    /**
     * 实例化一个UiHandler处理
     */
    protected Handler mUiHandler = new UiHandler(this) {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (getFragmentReference() != null && getFragmentReference().get() != null) {
                try {
                    getFragmentReference().get().handleUiMessage(msg);
                } catch (IllegalStateException e) {
                }
            }
        }

        ;
    };

    /**
     * 自定义UiHandler,用于处理其他线程发送的消息
     *
     * @author dane55
     */
    private static class UiHandler extends Handler {
        // 定义BaseFragment的弱引用，以保证虚拟机随时可以回收此页面
        private final WeakReference<BaseMVCActivity> mActivityReference;

        /**
         * 构建自定义的UIHandler，传递当前页面引用(Activity或者BaseFragment)
         *
         * @param activity
         */
        public UiHandler(BaseMVCActivity activity) {
            mActivityReference = new WeakReference<BaseMVCActivity>(activity);
        }

        /**
         * 获取当前页面(Activity或者BaseFragment)
         *
         * @return
         */
        public WeakReference<BaseMVCActivity> getFragmentReference() {
            return mActivityReference;
        }
    }

    /**
     * 处理更新UI任务(派生类需要重写此方法，用于处理自身业务)
     *
     * @param msg
     */
    protected void handleUiMessage(Message msg) {
    }

    /**
     * 发送UI更新操作
     *
     * @param msg
     */
    protected void sendUiMessage(Message msg) {
        mUiHandler.sendMessage(msg);
    }


    /**
     * 发送UI更新操作
     *
     * @param what
     */
    protected void sendEmptyUiMessage(int what) {
        mUiHandler.sendEmptyMessage(what);
    }
}
